home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 141_01.zip / HDWLIB.C < prev    next >
Text File  |  1993-06-01  |  15KB  |  470 lines

  1. /* hdwlib.c -- hardware library -- contents:    1984 may 4
  2.     read & set date/time - Newclock80
  3.          primitives for graphics peripheral - TMS9918a
  4.     cursor-control for TRS-80 screen w/ Omikron bios
  5.     PM Krasno 17813 Kiowa Trail Los Gatos CA 95030
  6. */
  7.  
  8. #include "bdscio.h"
  9. #define short char
  10. #define byte char
  11. #define K 1024
  12.  
  13. /* -- fcns to read & set Newclock80    */
  14.  
  15. unsigned tim_dif (d, t1, t2) char *d, *t1, *t2 ; 
  16. /* time difference in seconds, up to 18hrs or so */ {
  17.     char *t ; int n ; unsigned dif ;
  18.     unsigned val[12] ; /* seconds, each digit-position */
  19.     val[6] = 36000 ;    val[7] =  3600 ; /* hrs */
  20.     val[8] =   600 ;    val[9] =    60 ; /* min */
  21.     val[10] =   10 ;    val[11] =    1 ; /* sec */
  22.      n = 0 ; /* digit counter */
  23.     while ( t1[n] && t1[n] == t2[n] ) /* leading zeroes */
  24.         ++n ; 
  25.     if ( t1[n] < t2[n] ) /* if negative, swap pointers */
  26.         { t = t1 ; t1 = t2 ; t2 = t  ; }
  27.     if ( n < 6 ) return 65535 ; /* error - day changed */
  28.     for (dif = 0 ; n < 12 ; ++n)
  29.         dif += val[n] * (t1[n] - t2[n]) ;    
  30.     return dif ;
  31. } /* tim_dif */
  32.  
  33. #define clock_port 0xB0        /* Newclock80 base port */
  34. #define clock_digs 13        /* # data digits    */
  35.  
  36. syst_d (d) char *d ; { /* system date/time, "yymddhhmmss" */
  37. /* read Newclock80, ASCII format    */
  38. #define day_dig 6
  39.     /* compare tens of seconds before & after,
  40.         in case of rollover */
  41.     byte bef, aft ; int i, j ;
  42.  
  43.     aft = 0xF & inp (clock_port + 1) ;
  44.     do {    bef = aft ;
  45.         for (i = clock_digs - 1, j = 0 ; 0 <= i ; 
  46.             --i, ++j )
  47.             if ( i == day_dig ) --j ; /* skip weekday*/
  48.             else d[j] = '0' + (inp (clock_port + i) &
  49.             (((j==4) | (j==6)) ? 0x3 : 0xF) ) ;
  50.         aft = 0xF & inp (clock_port + 1) ;
  51.     } while ( bef != aft ) ;
  52.     d[clock_digs-1] = 0 ;
  53. #undef day_dig
  54. } /* sys_d */
  55.  
  56. read_clock (d_t) byte *d_t ;    {
  57.     /* compare tens of seconds before & after,
  58.         in case of rollover */
  59.     byte tens_bef, tens_aft ; int i, j ;
  60.  
  61.     tens_aft = 0xF & inp (clock_port + 1) ;
  62.     do {    tens_bef = tens_aft ;
  63.         for (i = clock_digs - 1, j = 0 ; 0 <= i ; 
  64.             --i, ++j )
  65.             d_t[j] = 0xF & inp (clock_port + i) ;
  66.         tens_aft = 0xF & inp (clock_port + 1) ;
  67.     } while ( tens_bef != tens_aft ) ;
  68. } /* read_clock */
  69.  
  70. show_clock (d_t) byte *d_t ;    {
  71.     int i, j, digit ; char *ptr ;
  72.     ptr = "SunMonTueWedThuFriSat" ;    /* quasi-static */
  73.     for (i = clock_digs, j = 0 ; 0 < i ; --i, ++j)    {
  74.         digit = d_t[j] ;
  75.         switch (j)    { 
  76.         case 4:        digit &= 0x3 ;
  77.         case 2:          puts ("/") ; break ;
  78.         case 7:        digit &= 0x3 ; break ;
  79.         case 9: case 11: puts (":") ; break ;
  80.         default : ;    } /* punctuation, masking */
  81.         if ( j != 6 ) putchar (0x30 + digit) ;
  82.         else printf (" %3.3s ",
  83.             ptr + 3 * (0x7 & digit)) ;
  84.     } /* for all digits */
  85.     putchar ('\n') ;
  86. } /* show_clock */
  87.  
  88. set_clock (d_t, n) byte *d_t ; int n ;    { /* n = offset */
  89.     int i, j ;
  90.     for (i = clock_digs - 1 - n, j = n ; 0 <= i ; --i, ++j)
  91.         outp (clock_port + j, 0xF & d_t[i]) ;
  92. } /* set_clock */
  93. #undef clock_digs
  94. #undef clock_port
  95.  
  96. /*  - primitives for CHROMAtrs/TMS9918A graphics */
  97. /* after an .asm package marked 
  98.     "(c) 1982 South Shore Computer Concepts, Hewlett, NY"
  99.     rewritten (NOT copied!) in BDS C 1983 Sep pmk */
  100. /* vram addresses cleaned up, text mode added 1984 may pmk */
  101. #define stat_port 0x79        /* CHROMAtrs port address */
  102. #define reg_port  0x79
  103. #define add_port  0x79
  104. #define data_port 0x78        /* CHROMAtrs vram read/write */
  105. #define STICK     0x7D        /* joystick */
  106. #define ena_port  0xEC        /* TRS-80 MOD III I/O BUS */
  107. #define PAT_GEN    0    /* pattern gen vram loc    */
  108. #define PAT_NAM    0x1800    /* pattern name table      */
  109. #define SPR_ATT    0x1C00    /* sprite attribute table  */
  110. #define PAT_COL    0x2000    /* pattern color table     */
  111. #define SPR_PAT    0x3800    /* sprite pattern table    */
  112. #define WH 15    /* colors */
  113. #define BL 1
  114.  
  115. vram_out (addr, data)    /* output to vram thru tms9918a */
  116. unsigned addr, data ;    {
  117. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  118.     outp (reg_port, 0xFF & addr) ;    /* LSB */
  119.     outp (reg_port, 0x40 | (0x3F & (addr>>8 ))) ;
  120.         /* MSB, flags (asm needs NOP for timing ? */
  121.     outp (data_port, data) ;    /* 1st data byte */
  122. } /* vram_out */
  123.  
  124. vram_o_m (addr, data, count) /* out data byte count times */
  125. unsigned addr, data, count ;    {
  126. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  127.     outp (reg_port, 0xFF & addr) ;
  128.     outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
  129.     while ( count-- ) outp (data_port, data) ;
  130. } /* vram_o_m */
  131.  
  132. vram_o_2 (addr, data1, data2) /* out 2 data bytes */
  133. unsigned addr, data1, data2 ;    {
  134. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  135.     outp (reg_port, 0xFF & addr) ;
  136.     outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
  137.     outp (data_port, data1) ;
  138.     outp (data_port, data2) ;
  139. } /* vram_o_2 */
  140.  
  141. vram_o_a (addr, pdata, count) /* out count bytes from array */
  142. unsigned addr, count ; char *pdata ;    {
  143. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  144.     outp (reg_port, 0xFF & addr) ;
  145.     outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
  146.     while ( count-- ) outp (data_port, *pdata++) ;
  147. } /* vram_o_a */
  148.  
  149. int vram_in (addr)    /* input from vram thru tms9918a */
  150. unsigned addr ;    {
  151. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  152.     outp (reg_port, 0xFF & addr) ;    /* LSB */
  153.     outp (reg_port, 0x3F & (addr>>8) ) ;
  154.     return inp (data_port) ;
  155. } /* vram_in */
  156.  
  157. vram_i_a (addr, pdata, count)    /* input count bytes */
  158. unsigned addr, count ; char *pdata ;    {
  159. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  160.     outp (reg_port, 0xFF & addr) ;
  161.     outp (reg_port, 0x3F & (addr>>8) ) ;
  162.     while ( count-- ) *pdata++ = inp (data_port) ;
  163. } /* vram_i_a */
  164.  
  165. vreg_out (reg, data)    /* output to vreg in tms9918a */
  166. unsigned reg, data ;    {
  167. /*M III    outp (ena_port) ; */    inp (stat_port) ;
  168.     outp (reg_port, data) ;        /* data */
  169.     outp (reg_port, 0x80 | reg) ;    /* reg #, flag */
  170. } /* vreg_out */
  171.  
  172. txt_mod ()    /* set up tms9918 text mode */    {
  173.     byte reg[8] ;    int i, j ;
  174.     reg[0] = 0x00 ;    /* M3 = 0, no video in */
  175.     reg[1] = 0x80 | 0x10 | 0x02 ;
  176.         /* 4116, blank, M1=1, size 8, mag 1X */
  177.     reg[2] = PAT_NAM / 0x400 ;    /* PAT_NAM msb */
  178.     reg[3] = PAT_COL / 0x40 ;    /* PAT_COL msb */
  179.     reg[4] = PAT_GEN / 0x800 ;    /* PAT_GEN msb */
  180.     reg[5] = SPR_ATT / 0x80 ;    /* SPR_ATT msb */
  181.     reg[6] = SPR_PAT / 0x80 ;    /* SPR_PAT msb */
  182.     reg[7] = (WH << 4) | BL ;    /* text, bkgr color */
  183.     for (i = 7 ; 0 <= i ; --i)
  184.         vreg_out (i, reg[i]) ;
  185.     vram_o_m (0, 0, 16 * K) ;
  186.     vram_o_m (PAT_NAM, ' ', 40 * 24) ;
  187.     txt_font ("b:font.def") ; 
  188.     vreg_out (1, reg[1] | 0x40) ; /* un-blank */
  189. } /* txt_mod */
  190.  
  191. txt_font (file)    char *file ; {
  192. #define FSIZ 0x60
  193.     byte font[FSIZ][6] ; 
  194.     /* vertical dot-matrix images, 6 bytes/char */ 
  195.     char fontbuf[BUFSIZ] ;    int ifont[6], c, i, s ;
  196.     if (fopen (file, fontbuf) == ERROR)
  197.         printf ("%s ?\n", file) ;
  198.     while (TRUE)    {    /* one pattern per line, to EOF */
  199.         s = fscanf (fontbuf,
  200.             "%x: %x, %x, %x, %x, %x, %x, %x, %x ;",
  201.             & c, ifont, ifont+1, ifont+2,
  202.              ifont+3, ifont+4, ifont+5) ;
  203.         if (s == EOF || s == CPMEOF || c ==0xff) break;
  204.         else if (s == 7 && ' ' <= c && c <= 0x7f)  {
  205.             for (i = 5 ; i >= 0 ; i--)
  206.                 font[c-' '][i] = ifont[i] ;
  207.         } /* if good char */
  208.         else    printf ("trouble in %s at %02x\n",
  209.                 file, c) ;
  210.     } /* loop until EOF */
  211.     fclose (fontbuf) ;
  212.     wr_font (font) ;
  213. } /* txt_font */
  214.  
  215. wr_font (font) byte font[FSIZ][6] ; { /* write font to vram */
  216.     int i, j, k ; byte f[FSIZ][8] ;
  217.     for (i = FSIZ-1 ; 0 <= i ; --i)    /* transpose */
  218.         for (k = 0 ; k < 8 ; ++k)    /* row */
  219.         for (f[i][k] = j = 0 ; j < 6 ; ++j) /* col */
  220.             f[i][k] |=
  221.              ( (font[i][j] << (7-k) ) & 0x80) >> j ;
  222.     vram_o_a (PAT_GEN + 8 * ' ', f, FSIZ * 8) ;
  223. } /* wr_font */
  224. #undef FSIZ
  225.  
  226. txt_ch (l, c, ch) int l, c ; char ch ; { /* write text char */
  227.     vram_out (PAT_NAM + 40 * (l-1) + c-1, ch) ;
  228. } /* txt_ch */
  229.  
  230. sh_ch (f) char *f ; {
  231.     int r, c ;
  232.     for (printf("\N"),r=0 ; r<8 ; ++r, printf("\N") )
  233.         for (c=0 ; c<8 ; ++c)
  234.             printf("%s", f[r] & (0x80 >> c) ? 
  235.                 "**":"  ") ;
  236. } /* sh_ch */
  237.  
  238. mode2 ()    /* set up tms9918 graphics mode 2 */    {
  239.     byte reg[7] ;    int i ;
  240.     reg[0] = 0x02 ;    /* M3 = 1, no video in */
  241.     reg[1] = 0x80 | 0x40 | 0x02 ;
  242.         /* 4116, active, size 8, mag 1X */
  243.     reg[2] = PAT_NAM / 0x400 ;    /* PAT_NAM msb */
  244.     reg[3] = 0xFF ; /* ??? */
  245.     reg[4] = 0x03 ; /* ??? */
  246.     reg[5] = SPR_ATT / 0x80 ;    /* SPR_ATT msb */
  247.     reg[6] = SPR_PAT / 0x80 ;    /* SPR_PAT msb */
  248.     for (i = 6 ; i >= 0 ; i--)
  249.         vreg_out (i, reg[i]) ;
  250. } /* mode2 */
  251.  
  252. cls (back_gr, fore_gr)        /* clear screen */
  253. unsigned back_gr, fore_gr ;        {
  254.     unsigned i, color ;
  255.     color = (fore_gr << 4) | back_gr ;
  256.     vram_out (PAT_NAM, 0) ;    /* clear pattern name table */
  257.     for (i = 1 ; i < 0x0300 ; i++) outp (data_port, i) ;
  258.     vram_o_m (PAT_GEN, 0, 0x1800) ;
  259.         /* clear pattern generator table */
  260.     vram_o_m (PAT_COL, color, 0x1800) ;
  261.         /* clear pattern color table */
  262.     vreg_out (7, 0x0C) ;    /* backdrop color */
  263. } /* cls */
  264.  
  265. spr_init ()    /* clear sprite pattern table */    {
  266.     vram_o_m (SPR_PAT, 0, 2048) ;
  267. } /* spr_init */
  268.  
  269. spr_def (pat_num, pat)    /* define sprite pattern */
  270. char pat_num, pat[32];    {    int i ;
  271.     if ( pat_num > 63 ) return ;
  272.     vram_o_a (SPR_PAT + (pat_num<<5), pat, 32) ;
  273. } /* spr_def */
  274.  
  275. spr_patc (sp_num, pat_num, col)    /* set sprite pattern, color */
  276. char sp_num, pat_num, col;    {
  277.     if ( (sp_num > 31) | (pat_num > 63) ) return ;
  278.     vram_o_2 (SPR_ATT + (sp_num<<2) + 2, pat_num<<2, col) ;
  279. } /* spr_patc */    
  280.  
  281. spr_mov (sp_num, x, y)    /* move sprite to x, y */
  282. char sp_num, x, y ;    {
  283.     if ( sp_num > 31 ) return ;
  284.     vram_o_2 (SPR_ATT + (sp_num<<2), y-1, x) ;
  285.             /* hdw bug ? needs y-1 ! */
  286. } /* spr_mov */
  287.  
  288. ld_font (font)    /* load font.def, define characters */    
  289. short font[0x60][6] ; /* dot-matrix images, 6 bytes/char */ {
  290.     char fontbuf[BUFSIZ] ;
  291.     int ifont[6], c, i, s ;
  292.     if (fopen ("font.def", fontbuf) == ERROR)
  293.         printf ("font.def ?\n") ;
  294.     while (TRUE)    {    /* one pattern per line, to EOF */
  295.         s = fscanf (fontbuf,
  296.             "%x: %x, %x, %x, %x, %x, %x, %x, %x ;",
  297.             & c, ifont, ifont+1, ifont+2,
  298.              ifont+3, ifont+4, ifont+5) ;
  299.         if (s == EOF || s == CPMEOF || c ==0xff) break;
  300.         else if (s == 7 && ' ' <= c && c <= 0x7f)  {
  301.             for (i = 5 ; i >= 0 ; i--)
  302.                 font[c-' '][i] = ifont[i] ;
  303.         } /* if good char */
  304.         else    printf ("%s %02x:\n",
  305.                 "trouble in font.def at", c) ;
  306.     } /* loop until EOF */
  307.     fclose (fontbuf) ;
  308. } /* ld_font */
  309.  
  310. cbar ()    /* draw colored bars */    {
  311.     unsigned i, x, y, color ; char *addr, bit_m ;
  312.     for (x = 0, y = 56, color = 1 ;
  313.         color < 15 ;
  314.         x += 8, y += 8, color++)    {
  315.         xycalc (x, y, &addr, &bit_m) ;
  316.         for (i = 0 ; i < 8*18 ; i++)
  317.             vram_out (PAT_COL+addr++,color);
  318.     } /* for x, y */
  319. } /* cbar */
  320.  
  321. wr_str (font, x, y, foregr, text)    /* write string */
  322. unsigned x, y, foregr ;    char **font, *text ;    {
  323.     while (*text) {
  324.         wr_ch (font, x, y, foregr, *text++) ;
  325.         x += 6 ;
  326.     } /* while */
  327. } /* wr_str */
  328.  
  329. wr_ch(font, x, y, foregr, ch)    /* write char to screen, G2 */
  330. short font[0x60][6] ; unsigned x, y, foregr, ch ;    {
  331.     /* doit the hard way - bit-by-bit in GR2 mode */
  332.     /* this means 48*6 outp's PER CHARACTER - optimise ! */
  333.     unsigned xi, i, yj, ym, col ;
  334.     for (xi = x, i = 0 ; i < 6 ; xi++, i++)
  335.         for (yj = y, ym = 1 ; ym ; yj++, ym <<= 1)
  336.             if (ym & font[ch-' '][i])
  337.                     set (xi, yj, foregr) ;
  338.             else  reset (xi, yj) ;
  339. } /* wr_ch */
  340.  
  341. follow (sprite, stk, pat, off, col, x, y)
  342. /* track joystick stk with sprite */
  343. unsigned sprite, stk, pat, off, col, x, y ;    {
  344.     short stick, dir, fire, oldf, draw ;
  345.     unsigned xdel, ydel, paddle, loop ;
  346.     spr_patc (sprite, pat, col) ;    /* display it    */
  347.     oldf = draw = FALSE ;
  348.     while ( TRUE )    {
  349.         spr_mov (sprite, x-off, y-off) ;
  350.         stick = ~inp (STICK + stk) ;  fire = stick & 0x10 ;
  351.         if ( fire && (! oldf) ) draw = ( ! draw ) ;
  352.         oldf = fire ;  /* flip draw when fire pushed */
  353.         if (stick & 1) x++ ;    if (stick & 2) x-- ;
  354.         if (stick & 4) y++ ;    if (stick & 8) y-- ;
  355.         if (x == 0xF8) x = 0x08 ;  if (x == 0x07) x = 0xF7;
  356.         if (y == 0xB8) y = 0x08 ;  if (y == 0x07) y = 0xB7;
  357.         if ( draw ) set(x, y, col); else printf (" \b \b");
  358.     } /* forever */
  359. } /* follow */
  360.  
  361. line (x1, y1, x2, y2, color) /* draw line (x1,y1) to (x2,y2) */
  362. short x1, x2, y1, y2 ; int color ; {
  363.     /* Bresenham's Algorithm, MiniMicro Systems Nov 1983 */
  364.     int t, a, b, xd, yd, dx, dy, x, y ;
  365.     set (x1, y1, color) ;        /* plot end pt */
  366.     dx = x2 - x1 ;    dy = y2 - y1 ; xd = yd = 1 ;
  367.     if ( (dx | dy) == 0 ) return ;
  368.     if ( dx < 0 ) { dx = - dx ; xd = -1 ; }
  369.     if ( dy < 0 ) { dy = - dy ; yd = -1 ; }
  370.     if ( dy < dx )    {
  371.         a = dy + dy ; t = a - dx ; b = t - dx ;
  372.         for (y = y1, x = x1 + xd ; x != x2 ; x += xd) {
  373. /*-> */            if ( t < 0 )    t += a ;
  374.             else { t += b ; y += yd ; }
  375.             set (x, y, color) ;
  376.         } /* for x */
  377.     } /* flat */
  378.     else {    a = dx + dx ; t = a - dy ; b = t - dy ;
  379.         for (x = x1, y = y1 + yd ; y != y2 ; y += yd) {
  380. /*-> */            if ( t < 0 )    t += a ;
  381.             else { t += b ; x += xd ; }
  382.             set (x, y, color) ;
  383.         } /* for y */
  384.     } /* steep */
  385.     set (x2, y2, color) ;
  386. } /* line */
  387.  
  388. set (h, v, col)        /* point on */
  389. unsigned h, v, col ;    {
  390.     unsigned offset, by, bit_m ;
  391.     by = xycalc (h, v, &offset, &bit_m) ;
  392.     vram_out (PAT_GEN + offset, by | bit_m) ;
  393.     if ( col <= 15 ) {  /* set color */
  394.         by = vram_in (PAT_COL + offset) ;
  395.         vram_out (PAT_COL + offset, 
  396.         (col<<4) | (0x0F & by)) ;
  397.     } /* color */
  398. } /* set */
  399.  
  400. reset (h, v)        /* point off */
  401. unsigned h, v ;    {
  402.     unsigned offset, by, bit_m ;
  403.     by = xycalc (h, v, &offset, &bit_m) ;
  404.     vram_out (offset, by & ~bit_m) ;
  405. } /* reset */
  406.  
  407. test (h, v)        /* test point */
  408. unsigned h, v ;    {
  409.     unsigned offset, by, bit_m ;
  410.     by = xycalc (h, v, &offset, &bit_m) ;
  411.     return (by & bit_m) ;
  412. } /* test */
  413.  
  414. xycalc (h, v, offset, b_m)    /* find byte & bit for (h, v) */
  415. unsigned h, v, *offset, *b_m ;    {
  416.     *b_m = 0x80 >> (h & 0x07) ;
  417.     *offset = ((v & 0xF8) << 5) | (h & 0xF8) | (v & 0x07) ;
  418.     return (vram_in (PAT_GEN + *offset)) ;
  419. } /* xycalc */
  420.  
  421. #define TEST 0xA5
  422. vram_test ()     /* write vram, read back */    {
  423.     int i, in;
  424.     vram_out (0, TEST) ;
  425.     for (i = 1 ; i < 16*1024; i++)
  426.         outp (data_port, TEST) ;
  427.     if ((in = vram_in (0)) != TEST)
  428.         vram_err (0, in, TEST);
  429.     for (i = 1 ; i < 16*1024 ; i++)
  430.         if ((in = inp (data_port)) != TEST)
  431.             vram_err (i, in, TEST) ;
  432. } /* vram_test */
  433. #undef TEST
  434.  
  435. vram_err (l, r, w)    {
  436.     printf ("vram err-loc %04x: wrote %02x, read %02x\n",
  437.         l, w, r) ;
  438. } /* vram_err */
  439. #undef stat_port
  440. #undef reg_port
  441. #undef add_port
  442. #undef data_port
  443. #undef STICK
  444. #undef ena_port
  445. #undef PAT_GEN
  446. #undef PAT_NAM
  447. #undef SPR_ATT
  448. #undef PAT_COL
  449. #undef SPR_PAT
  450. #undef WH
  451. #undef BL
  452.  
  453. /* TRS-80 screen cursor control, etc */
  454. clear ()    {    /* clear screen, home cursor */
  455.     bios (4, 0x1b) ; bios (4, '*') ;    return;
  456. } /* clear */
  457.  
  458. cursor (l, c) int l, c ;    {
  459. /* position cursor to line l, col c */
  460.     bios (4, 0x1b) ;   bios (4, '=') ;    
  461.     bios (4, 0x20+l) ; bios (4, 0x20+c) ;
  462. } /* cursor */
  463.  
  464. curpr (l, c, s)    int l, c; char *s ; {
  465. /* position cursor & print string */
  466.     cursor (l,c) ; puts (s) ; return c+strlen(s) ;
  467. } /* curpr */
  468.  
  469. or (i = 1 ; i < 16*1024; i++)
  470.         outp (data_por